package com.copyurl.actions;

import com.copyurl.common.SpringAnnotations;
import com.copyurl.notification.NotificationManage;
import com.copyurl.util.PropertiesUtil;
import com.copyurl.util.PsiElementUtil;
import com.copyurl.util.SpringUtil;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import org.apache.commons.lang3.StringUtils;

import java.awt.datatransfer.StringSelection;
import java.util.Properties;

public class CopyFullUrlAction extends AnAction {

    @Override
    public void actionPerformed(AnActionEvent e) {
        PsiElement psiElement = e.getData(PlatformDataKeys.PSI_ELEMENT);
        String queryList = "";
        if (psiElement != null) {
            PsiMethod psiMethod = (PsiMethod) psiElement;
            PsiClass psiClass = psiMethod.getContainingClass();
            PsiModifierList classModifierList = psiClass.getModifierList();
            PsiModifierList methodModifierList = psiMethod.getModifierList();
            String classUrl = PsiElementUtil.getUrl(classModifierList, SpringAnnotations.REQUEST_MAPPING_QUALIFIED_NAME);
            String methodUrl = "";
            if (SpringUtil.containsSpringAnnotation(SpringAnnotations.REQUEST_MAPPING_QUALIFIED_NAME, methodModifierList)) {
                methodUrl = PsiElementUtil.getUrl(methodModifierList, SpringAnnotations.REQUEST_MAPPING_QUALIFIED_NAME);
                String httpMethod = PsiElementUtil.getAnnotationValue(methodModifierList, "method", SpringAnnotations.REQUEST_MAPPING_QUALIFIED_NAME);
                if (httpMethod.equalsIgnoreCase("GET") || httpMethod.equalsIgnoreCase("RequestMethod.GET") || httpMethod.isEmpty()) {
                    queryList = PsiElementUtil.createQueryWithParameters(psiMethod.getParameterList());
                }
            } else if (SpringUtil.containsSpringAnnotation(SpringAnnotations.GET_MAPPING_QUALIFIED_NAME, methodModifierList)) {
                methodUrl = PsiElementUtil.getUrl(methodModifierList, SpringAnnotations.GET_MAPPING_QUALIFIED_NAME);
                queryList = PsiElementUtil.createQueryWithParameters(psiMethod.getParameterList());
            } else if (SpringUtil.containsSpringAnnotation(SpringAnnotations.POST_MAPPING_QUALIFIED_NAME, methodModifierList)) {
                methodUrl = PsiElementUtil.getUrl(methodModifierList, SpringAnnotations.POST_MAPPING_QUALIFIED_NAME);
            } else if (SpringUtil.containsSpringAnnotation(SpringAnnotations.PATCH_MAPPING_QUALIFIED_NAME, methodModifierList)) {
                methodUrl = PsiElementUtil.getUrl(methodModifierList, SpringAnnotations.PATCH_MAPPING_QUALIFIED_NAME);
            } else if (SpringUtil.containsSpringAnnotation(SpringAnnotations.DELETE_MAPPING_QUALIFIED_NAME, methodModifierList)) {
                methodUrl = PsiElementUtil.getUrl(methodModifierList, SpringAnnotations.DELETE_MAPPING_QUALIFIED_NAME);
            } else if (SpringUtil.containsSpringAnnotation(SpringAnnotations.PUT_MAPPING_QUALIFIED_NAME, methodModifierList)) {
                methodUrl = PsiElementUtil.getUrl(methodModifierList, SpringAnnotations.PUT_MAPPING_QUALIFIED_NAME);
            }

            String url = "http://localhost:" +
                    this.getPortAndContextPath(e.getData(CommonDataKeys.PROJECT)) +
                    classUrl +
                    methodUrl +
                    queryList;
            CopyPasteManager.getInstance().setContents(new StringSelection(url));
            NotificationManage.successNotification("复制成功");
        }

    }

    private String getPortAndContextPath(Project project) {
        StringBuilder url = new StringBuilder();
        // 读取配置
        Properties properties = PropertiesUtil.getProperty(project, "application.yml");
        // 获取端口号
        String port = properties.getProperty("server.port");
        url.append(port.isEmpty() ? 8080 : port);
        // 获取系统路径
        String systemPath = properties.getProperty("server.servlet.context-path");
        if (systemPath == null) {
            systemPath = properties.getProperty("server.context-path");
        }
        if (StringUtils.isNotBlank(systemPath) && !systemPath.startsWith("/")) {
            systemPath = "/" + systemPath;
        }
        url.append(systemPath);

        return url.toString();
    }

    @Override
    public void update(AnActionEvent e) {
        try {
            Project project = e.getData(CommonDataKeys.PROJECT);
            Editor editor = e.getData(CommonDataKeys.EDITOR);
            VirtualFile virtualFile = editor.getVirtualFile();
            PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);

            PsiElement psiElement = psiFile.findElementAt(editor.getCaretModel().getOffset());
            PsiMethod psiMethod = PsiTreeUtil.getParentOfType(psiElement, PsiMethod.class);
            PsiClass psiClass = psiMethod.getContainingClass();
            boolean available = SpringUtil.isRestMethod(psiMethod.getModifierList())
                    && (SpringUtil.containsSpringAnnotation(SpringAnnotations.CONTROLLER, psiClass.getModifierList())
                    || SpringUtil.containsSpringAnnotation(SpringAnnotations.REST_CONTROLLER, psiClass.getModifierList()));

            e.getPresentation().setEnabled(project != null && available);
        } catch (Exception exception) {
            e.getPresentation().setVisible(false);
        }
    }

}
